package com.chzn.component;

import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory;
import org.springframework.stereotype.Component;

/**
 * @see org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation
 * (java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition)
 * <p>
 * 在创建bean的时候,先调用实例化前的后置处理器回调 然后 根据是有有返回bean 有返回则 直接调用初始化后的后置处理器回调 中间绕过了很多过程
 * 此InstantiationAwareBeanPostProcessor后置处理器的相同方法回调先于SmartInstantiationAwareBeanPostProcessor 回调
 */

@Component
public class UserServiceInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

	/**
	 * TODO  在实例化前回调时 如果返回的不为null 则直接调用初始化后回调
	 * if (targetType != null) {
	 * 		bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
	 * 			if (bean != null) {
	 * 				bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
	 * 			}
	 * 	}
	 * @see AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition)
	 * @return  返回为null时 调用下一个实例化前BeanPostProcessors(列表) 当返回不为空时,调用初始化后回调
	 */
	@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		if (UserService.class.equals(beanClass)) {
			System.out.println("实例化前");
		}
		return null;
	}

	@Override
	public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
		if ("userService".equals(beanName)) {
			System.out.println("实例化后");
		}
		return true;
	}

	/**
	 * @see AutowiredAnnotationBeanPostProcessor#postProcessProperties(org.springframework.beans.PropertyValues, java.lang.Object, java.lang.String)
	 * spring内部定义了此BeanPostProcessor  并在实例化AnnotationConfigApplicationContext的时候注册到BeanDefinitionMap中
	 */
	@Override
	public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
		if ("userService".equals(beanName)) {
			System.out.println("属性填充后");
		}
		return null;
	}


	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		if ("userService".equals(beanName)) {
			System.out.println("初始化前");
		}
		return null;
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if ("userService".equals(beanName)) {
			System.out.println("初始化后");
		}
		return null;
	}
}
